/************************************************************************************************************
* File Name:CamOperate.cpp
* Abstract :funtion for operating camera
* 
* Version :1.1
* Author  :Liu Tengfei
* Date    :2013.12.1
*
* Shanghai Ruishi Machine Vision Technology Co., Ltd.
* All rights reserved.
*************************************************************************************************************/
#include "StdAfx.h"
#include "CamOperate.h"
#include "SocketUtil.h"
#include <stdio.h>

//io iso configuration

CCamOperate::CCamOperate(void)
{
	m_hThreadProcess = NULL;
	m_hSemCMDItems = NULL;
	m_nThreadWatch = 0;
	m_nConnect = -1;
}

CCamOperate::~CCamOperate(void)
{
	Close();
}


//create signal and create thread
BOOL CCamOperate::Open()   
{
	if (m_hThreadProcess)
	{
		return FALSE;
	}
	
	m_hSemCMDItems = CreateSemaphore(NULL, 0, 99999, NULL);

	m_nThreadWatch = 1;
	m_hThreadProcess = (HANDLE)_beginthreadex(NULL, 0, &ThreadProcess, (void*)this, 0, NULL);
	m_nConnect = -1;

	memset(m_nCurClassSupportVerList,0,10*sizeof(int));
	m_nCurClassSupportVerList[CMD_CLASS_EAGLEEYE] = CMD_CLASS_EAGLEEYE_VER;
	m_nCurClassSupportVerList[CMD_CLASS_CHAMELEON] = CMD_CLASS_CHAMELEON_VER;
	m_nCurClassSupportVerList[CMD_CLASS_CHEETAH] = CMD_CLASS_CHEETAH;
	return TRUE;
}

 //close thread, close handle of thread, close handle of signal
void CCamOperate::Close() 
{
	if (m_hThreadProcess)
	{
		m_nThreadWatch = 0;
		if (WaitForSingleObject(m_hThreadProcess, 6000) == WAIT_TIMEOUT)
		{
			TerminateThread(m_hThreadProcess, -1);
		}
		CloseHandle(m_hThreadProcess);
		m_hThreadProcess = NULL;
	}

	if (m_hSemCMDItems)
	{
		CloseHandle(m_hSemCMDItems);
		m_hSemCMDItems = NULL;
	}
}

//set IP
int CCamOperate::SetDevAddr(HWND hWndNotify,const char *pIP, UINT16 port)  
{
	char szTemp[40];

	*(UINT16*)szTemp = port;
	sprintf_s(szTemp + 2, 38, "%s", pIP);

	return SendCMD(hWndNotify, CMD_CHANGE_DEV_IP, 0, szTemp, 40);
}

int CCamOperate::SendCMD(HWND hWndNotify, UINT32 attribute, UINT32 method)
{
	return SendCMD(hWndNotify, attribute, method, NULL, 0);
}

int CCamOperate::SendCMD(HWND hWndNotify, UINT32 attribute, UINT32 method, UINT32 param)
{
	return SendCMD(hWndNotify, attribute, method, (const char*)&param, sizeof(param));
}

int CCamOperate::SendCMD(HWND hWndNotify, UINT32 attribute, UINT32 method, const char *pParam)
{
	return SendCMD(hWndNotify, attribute, method, pParam, (int)(strlen(pParam) + 1));
}

int CCamOperate::SendCMD(HWND hWndNotify, UINT32 attribute, UINT32 method, const char *pParam, int size) 
{
	if (m_nConnect < 0)
	{
		return -1;
	}
	CMDItem_t item;
	memset(&item, 0, sizeof(item));
	item.hWndNotify = hWndNotify;
	item.attribute = attribute;
	item.method = method;
	item.dataSendLen = size;
	if (size > 0)
	{
		item.pDataSend = new char[size];
		if (item.pDataSend == NULL)
		{
			return -2;
		}
		memcpy(item.pDataSend, pParam, size);
	}

	return SendCMD(item);
}

//put cmdItem into the list called "m_listCMDItems"
int CCamOperate::SendCMD(const CMDItem_t &cmdItem)  
{
	CAutoLock al(&m_csAccessCMDItems);
	m_listCMDItems.push_back(cmdItem);
	ReleaseSemaphore(m_hSemCMDItems, 1, NULL);

	return 0;
}

//get the first member of the list called "m_listCMDItems"
BOOL CCamOperate::FetchTopCMDItem(CMDItem_t &cmdItem, UINT32 timeout)  
{
	if (WaitForSingleObject(m_hSemCMDItems, timeout) == WAIT_TIMEOUT)
	{
		return FALSE;
	}

	CAutoLock al(&m_csAccessCMDItems);
	if (m_listCMDItems.empty())
	{
		return FALSE;
	}
	cmdItem = m_listCMDItems.front();   
	m_listCMDItems.pop_front();

	return TRUE;
}

//thread of processing command list 
unsigned __stdcall CCamOperate::ThreadProcess(void * pParam)
{
	CCamOperate *pThis = (CCamOperate*)pParam;
	CMDItem_t curItem;
	CSendCmdToDev *pCmdToDev = pThis->m_pCmdToDev;
	int ret = -1;
	
	while (pThis->m_nThreadWatch)
	{
		if (!pThis->FetchTopCMDItem(curItem, 300))
		{
			continue;
		}
		
		if (!pThis->m_pCmdToDev)
		{
			continue;
		}

		ret = pCmdToDev->SendCMD(curItem.attribute, curItem.method, (const char*)curItem.pDataSend, curItem.dataSendLen);

		if (curItem.hWndNotify)
		{
			curItem.pDataBack = const_cast<char*>(pCmdToDev->GetBackDataPtr());
			curItem.pMsg = const_cast<char*>(pCmdToDev->GetBackMsgPtr());
			curItem.dataBackLen = pCmdToDev->GetBackDataLen();
			curItem.result = pCmdToDev->GetCmdResult();
			::SendMessage(curItem.hWndNotify, MSG_NOTIFY_CMD_FINISH, (WPARAM)&curItem, (LPARAM)ret);
		}

		if (curItem.dataSendLen > 0)
		{
			delete[] curItem.pDataSend;
			curItem.pDataSend = NULL;
			curItem.dataSendLen = 0;
		}
			
	}
	return 0;
}


int CCamOperate::Disconnect()
{
	m_nConnect = -1;
	return 0;
}

int CCamOperate::Connect()
{
	m_nConnect = 0;
	return 0;
}

int CCamOperate::ConnectSuccess()
{
	m_nConnect = 1;
	return 0;
}

BOOL CCamOperate::IsConnection()
{
	if (0 < m_nConnect)
	{
		return TRUE;
	}
	return FALSE;
}

int CCamOperate::SDSendCommand(const char *pTargetIP,BYTE byteCMD,const char *pParam1,const char *pParam2)
{
	BYTE cmdbuf[50];
	*cmdbuf = 0xff;
	cmdbuf[1] = 0x00;
	*(UINT*)(cmdbuf+2) = 35;
	cmdbuf[6] = (char)byteCMD;
	memcpy(cmdbuf+7,pParam1,17);
	memcpy(cmdbuf+24,pParam2,17);
	if (!SendCommand(pTargetIP, (char*)cmdbuf))
	{
		return -1;
	}
	return 0;
}


//send command to camera
BOOL CCamOperate::SendCommand(const char *pTargetIP, char *pCMDBuf, int nTimeout, char *pRecvBuf, int size)
{
	BOOL bResult = FALSE;
	SOCKET sockCMDClient = INVALID_SOCKET;
	do 
	{
		sockCMDClient = socket(AF_INET, SOCK_STREAM, 0);
		if (INVALID_SOCKET == sockCMDClient)
		{
			break;
		}

		setsockopt(sockCMDClient, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeout, sizeof(nTimeout));
		setsockopt(sockCMDClient, SOL_SOCKET, SO_RCVTIMEO, (char*)&nTimeout, sizeof(nTimeout));

		struct sockaddr_in camAddr;
		camAddr.sin_family = AF_INET;
		camAddr.sin_addr.s_addr = inet_addr(pTargetIP);
		camAddr.sin_port = htons(35000);

		int dataSize = 0;
		dataSize = (pCMDBuf[5]<<24) + (pCMDBuf[4]<<16) + (pCMDBuf[3]<<8) + pCMDBuf[2];
		if (!ConnectHasTimeout(sockCMDClient, &camAddr, nTimeout))
		{
			break;
		}

		if (!SafeSend(sockCMDClient, pCMDBuf, 6+dataSize))
		{
			break;
		}

		if (pCMDBuf[1] && pRecvBuf != NULL && size > 0)
		{
			int nDataLen = 0;
			if (!SafeRecv(sockCMDClient, (char*)&nDataLen, 4))
			{
				break;
			}
			if (nDataLen > size)
			{
				break;
			}
			if (!SafeRecv(sockCMDClient, pRecvBuf, nDataLen))
			{
				break;
			}
		}

		bResult = TRUE;
	} while(false);

	if (INVALID_SOCKET != sockCMDClient)
	{
		closesocket(sockCMDClient);
	}

	return bResult;
}


//
BOOL CCamOperate::exSendCommand(const char *pTargetIP,DWORD port,DWORD cmdHead,DWORD cmdLength,DWORD cmdReply ,char *pParaBuf, int nTimeout, char *pRecvBuf, int size)
{
	BOOL bResult = FALSE;
	SOCKET sockCMDClient = INVALID_SOCKET;
	char chSendBuf[12];
	DWORD recvlength = 0;
	do 
	{
		sockCMDClient = socket(AF_INET, SOCK_STREAM, 0);
		if (INVALID_SOCKET == sockCMDClient)
		{
			break;
		}

		setsockopt(sockCMDClient, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeout, sizeof(nTimeout));
		setsockopt(sockCMDClient, SOL_SOCKET, SO_RCVTIMEO, (char*)&nTimeout, sizeof(nTimeout));

		struct sockaddr_in camAddr;
		camAddr.sin_family = AF_INET;
		camAddr.sin_addr.s_addr = inet_addr(pTargetIP);;
		camAddr.sin_port = htons((u_short)port);
		if (!ConnectHasTimeout(sockCMDClient, &camAddr, nTimeout))
		{
			break;
		}
		*(DWORD*)chSendBuf = cmdHead; 
		*(DWORD*)(chSendBuf+4) = cmdLength; 
		*(DWORD*)(chSendBuf+8) = cmdReply; 
		if (!SafeSend(sockCMDClient, chSendBuf, 12))
		{
			break;
		}
		if (cmdLength>0)
		{
			if (!SafeSend(sockCMDClient, pParaBuf, cmdLength))
			{
				break;
			}
		}
		if(cmdReply != 0)
		{
			if (!SafeRecv(sockCMDClient,pRecvBuf,4))
			{
				break;
			}
			recvlength = (((DWORD)*(pRecvBuf+3))<<24) + (((DWORD)*(pRecvBuf+2))<<16 )+ (((DWORD)*(pRecvBuf+1))<<8) + ((DWORD)*pRecvBuf);
			if (!SafeRecv(sockCMDClient,pRecvBuf,recvlength))
			{
				break;
			}
		}		
		bResult = TRUE;
	} while(false);

	if (INVALID_SOCKET != sockCMDClient)
	{
		closesocket(sockCMDClient);
	}

	return bResult;
}

int CCamOperate::CaptureSingleFrame(HWND hWnd)
{
	return SendCMD(hWnd,CMD_ACQ_CAPTURE,CMD_METHOD_EXCUTE);
}

//switch camera running mode
int CCamOperate::SwitchMode(HWND hWnd,enum Roseek_SensorRunMode runMode)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = (DWORD)runMode;
	return SendCMD(hWnd,CMD_ACQ_MODE,CMD_METHOD_SET,cmdbuf,4);
}

//config adjust mode
int CCamOperate::SetAdjustMode(HWND hWnd,enum Roseek_SensorRunMode runMode,BOOL adjustMode)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = (DWORD)runMode;
	*(DWORD*)(cmdbuf + 4) = (DWORD)adjustMode;

	return SendCMD(hWnd,CMD_ACQ_PARA_ADJUST,CMD_METHOD_SET,cmdbuf,8);
}

//config specific mode shut time
int CCamOperate::SetShutTime(HWND hWnd,enum Roseek_SensorRunMode runMode,DWORD shutTime)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = (DWORD)runMode;
	*(DWORD*)(cmdbuf + 4) = (DWORD)shutTime;
	return SendCMD(hWnd,CMD_ACQ_SHUTTIME,CMD_METHOD_SET,cmdbuf,8);
}

//set specific mode gain
int	CCamOperate::SetGain(HWND hWnd,enum Roseek_SensorRunMode runMode,float gain)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = (DWORD)runMode;
	*(float*)(cmdbuf + 4) = gain;
	return SendCMD(hWnd,CMD_ACQ_GAIN,CMD_METHOD_SET,cmdbuf,8);
}

//set specific mode shutter time limit
int	CCamOperate::SetShutTimeLimit(HWND hWnd,enum Roseek_SensorRunMode runMode,DWORD shutTimeLimit)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = (DWORD)runMode;
	*(DWORD*)(cmdbuf + 4) = shutTimeLimit;
	return SendCMD(hWnd,CMD_ACQ_SHUT_LIMIT,CMD_METHOD_SET,cmdbuf,8);
}

//set specific mode shutter time low limit
int	CCamOperate::SetShutTimeLowLimit(HWND hWnd,enum Roseek_SensorRunMode runMode,DWORD shutTimeLowLimit)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = (DWORD)runMode;
	*(DWORD*)(cmdbuf + 4) = shutTimeLowLimit;
	return SendCMD(hWnd,CMD_ACQ_SHUT_LOWLIMIT,CMD_METHOD_SET,cmdbuf,8);
}

//set specific mode gain upper limit 
int CCamOperate::SetCurGainLimit(HWND hWnd, enum Roseek_SensorRunMode runMode,float gainlimit)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = (DWORD)runMode;
	*(float*)(cmdbuf + 4) = gainlimit;
	return SendCMD(hWnd,CMD_ACQ_GAIN_LIMIT,CMD_METHOD_SET,cmdbuf,8);
}

//Set expected brightness mean value
int	CCamOperate::SetExpLumi(HWND hWnd,enum Roseek_SensorRunMode runMode,BYTE value)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = (DWORD)runMode;
	*(DWORD*)(cmdbuf + 4) = (DWORD)value;
	return SendCMD(hWnd,CMD_ACQ_MEAN,CMD_METHOD_SET,cmdbuf,8);
}

//set image rotation
int	CCamOperate::SetImgRotate(HWND hWnd, DWORD rotation)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = rotation;
	return SendCMD(hWnd,CMD_ACQ_ROTATION,CMD_METHOD_SET,cmdbuf,4);
}

//Set image acquisition fps
int	CCamOperate::SetImgAcqFps(HWND hWnd, const char *fps)
{
	char cmdbuf[32];
	strcpy_s(cmdbuf,fps);
	return SendCMD(hWnd,CMD_ACQ_FPS,CMD_METHOD_SET,cmdbuf,32);
}


//Set image acquisition fps
int	CCamOperate::SetImgAcqFps(HWND hWnd, float fps)
{
	char cmdbuf[8];
	*(float*)cmdbuf = fps;
	return SendCMD(hWnd,CMD_ACQ_FPS,CMD_METHOD_SET,cmdbuf,4);
}

int	CCamOperate::SetJpegEncFps(HWND hWnd, const char *fps)
{
	char cmdbuf[32];
	strcpy_s(cmdbuf,fps);
	return SendCMD(hWnd,CMD_JPEG_ENC_FPS,CMD_METHOD_SET,cmdbuf,32);
}

int	CCamOperate::SetJpegEncFps(HWND hWnd, DWORD fps)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = fps;
	return SendCMD(hWnd,CMD_JPEG_ENC_FPS,CMD_METHOD_SET,cmdbuf,4);
}

//set image acquisition resolution
int	CCamOperate::SetImgAcqResolution(HWND hWnd, Roseek_SensorRunMode mode, const char* resolution)
{
	char cmdbuf[40];
	*(DWORD*)cmdbuf = (DWORD)mode;
	strcpy_s(cmdbuf+4,32,resolution);
	return SendCMD(hWnd,CMD_ACQ_IMG_RESOLUTION,CMD_METHOD_SET,cmdbuf,36);
}

//set image enhancement
int	CCamOperate::SetImgEnhancement(HWND hWnd, DWORD enhance)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = enhance;
	return SendCMD(hWnd,CMD_PROC_ENHANCEMENT,CMD_METHOD_SET,cmdbuf,4);
}

//set HDR level
int	CCamOperate::SetHdrLevel(HWND hWnd, DWORD level)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = level;
	return SendCMD(hWnd,CMD_PROC_HDR_LEVEL,CMD_METHOD_SET,cmdbuf,4);
}


//set image denoise
int	CCamOperate::SetImgDenoise(HWND hWnd, DWORD denoise)
{
	char cmdbuf[32];
	*(DWORD*)cmdbuf = denoise;
	return SendCMD(hWnd,CMD_PROC_DENOISE,CMD_METHOD_SET,cmdbuf,4);
}

//set color saturation
int	CCamOperate::SetImgColor(HWND hWnd,float color)
{
	char cmdbuf[8];
	*(float*)cmdbuf = color;
	return SendCMD(hWnd,CMD_PROC_COLOR,CMD_METHOD_SET,cmdbuf,4);
}

//enable auto white balance
int	CCamOperate::EnableWhiteBalance(HWND hWnd,BOOL enable)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = (DWORD)enable;
	return SendCMD(hWnd,CMD_PROC_AUTO_WB,CMD_METHOD_SET,cmdbuf,4);
}


//set white balance environment parameters
int	CCamOperate::SetWbEnvironment(HWND hWnd,const char* environment)
{
	char cmdbuf[32];
	strcpy_s(cmdbuf,environment);
	return SendCMD(hWnd,CMD_PROC_WB_ENVIRONMENT,CMD_METHOD_SET,cmdbuf,32);
}

//set white balance parameters
int	CCamOperate::SetWBParameters(HWND hWnd,float r,float g, float b)
{
	char cmdbuf[16];
	*(float*)cmdbuf = r;
	*(float*)(cmdbuf + 4) = g;
	*(float*)(cmdbuf + 8) = b;
	return SendCMD(hWnd,CMD_PROC_WB_PARAMS,CMD_METHOD_SET,cmdbuf,12);
}

//enable LUT
int	CCamOperate::EnableLut(HWND hWnd,BOOL enable)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = (DWORD)enable;
	return SendCMD(hWnd,CMD_PROC_LUT,CMD_METHOD_SET,cmdbuf,4);
}

//select LUT 
int	CCamOperate::SelectLut(HWND hWnd,DWORD num)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = num;
	return SendCMD(hWnd,CMD_PROC_LUT_NUM,CMD_METHOD_SET,cmdbuf,4);
}

//set lut data
int	CCamOperate::SetLutData(HWND hWnd,DWORD num, BYTE *lutData,BOOL save,int len)
{
	char *cmdbuf = NULL;
	int ret = 0;
	cmdbuf = new char[4200];
	if (!cmdbuf)
	{
		return -1;
	}
	*(DWORD*) cmdbuf = num;
	*(DWORD*)(cmdbuf + 4) = (DWORD)save;
	memcpy_s(cmdbuf+8,4096,lutData,len);
	ret = SendCMD(hWnd,CMD_PROC_LUT_DATA,CMD_METHOD_SET,cmdbuf,4104);
	delete[] cmdbuf;
	return ret;
}

//resume lut
int	CCamOperate::ResumeLut(HWND hWnd,DWORD num)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = num;
	return SendCMD(hWnd,CMD_PROC_RESUME_LUT,CMD_METHOD_EXCUTE,cmdbuf,4);
}

//set lut gamma 
int	CCamOperate::SetLutGamma(HWND hWnd,DWORD num, float gamma)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = num;
	*(float*)(cmdbuf+4) = gamma;
	return SendCMD(hWnd,CMD_PROC_GAMMA,CMD_METHOD_SET,cmdbuf,8);
}

//enable asic lut
int	CCamOperate::EnableAsicLut(HWND hWnd,BOOL enable)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = (DWORD)enable;
	return SendCMD(hWnd,CMD_PROC_ASIC_LUT,CMD_METHOD_SET,cmdbuf,4);
}

//set asic lut data
int	CCamOperate::SetAiscLutData(HWND hWnd,DWORD num, BYTE *lutData,BOOL save,int len)
{
	char *cmdbuf = NULL;
	int ret = 0;
	cmdbuf = new char[4200];
	if (!cmdbuf)
	{
		return -1;
	}
	*(DWORD*) cmdbuf = num;
	*(DWORD*)(cmdbuf + 4) = (DWORD)save;
	memcpy_s(cmdbuf+8,4096,lutData,len);
	ret = SendCMD(hWnd,CMD_PROC_ASIC_LUT_DATA,CMD_METHOD_SET,cmdbuf,4104);
	delete[] cmdbuf;
	return ret;
}

//resume asic lut
int	CCamOperate::ResumeAsicLut(HWND hWnd,DWORD num)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = num;
	return SendCMD(hWnd,CMD_PROC_RESUME_ASIC_LUT,CMD_METHOD_EXCUTE,cmdbuf,4);
}

//set asic lut gamma
int	CCamOperate::SetAsicLutGamma(HWND hWnd,DWORD num, float gamma)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = num;
	*(float*)(cmdbuf+4) = gamma;
	return SendCMD(hWnd,CMD_PROC_ASIC_GAMMA,CMD_METHOD_SET,cmdbuf,8);
}

//set digital gain
int	CCamOperate::SetDigitalGain(HWND hWnd,float gain)
{
	char cmdbuf[8];
	*(float*)cmdbuf = gain;
	return SendCMD(hWnd,CMD_PROC_DIGITAL_GAIN,CMD_METHOD_SET,cmdbuf,4);
}

//resume digital gain
int	CCamOperate::ResumeDigitalGain(HWND hWnd)
{
	return SendCMD(hWnd,CMD_PROC_RESUME_DIGITAL_GAIN,CMD_METHOD_EXCUTE);
}

//set lut mode
int	CCamOperate::SetLutMode(HWND hWnd,DWORD index,DWORD mode)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = index;
	*(DWORD*)(cmdbuf+4) = mode;
	return SendCMD(hWnd,CMD_PROC_LUT_MODE,CMD_METHOD_SET,cmdbuf,8);
}

//set asic lut mode
int	CCamOperate::SetAsicLutMode(HWND hWnd,DWORD mode)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = mode;
	return SendCMD(hWnd,CMD_PROC_ASIC_LUT_MODE,CMD_METHOD_SET,cmdbuf,4);
}

//set metering region
int	CCamOperate::SetMeteringRegion(HWND hWnd, DWORD num, DWORD startX, DWORD startY, DWORD endX, DWORD endY)
{
	char cmdbuf[32];
	*(DWORD*)cmdbuf = num;
	*(DWORD*)(cmdbuf+4) = startX;
	*(DWORD*)(cmdbuf+8) = startY;
	*(DWORD*)(cmdbuf+12) = endX;
	*(DWORD*)(cmdbuf+16) = endY;
	return SendCMD(hWnd,CMD_ACQ_METER_REGION,CMD_METHOD_SET,cmdbuf,20);
}

//set image acquisition format
int	CCamOperate::SetImgAcqFormat(HWND hWnd,const char* format)
{
	char cmdbuf[32];
	strcpy_s(cmdbuf,format);
	return SendCMD(hWnd,CMD_ACQ_FORMAT,CMD_METHOD_SET,cmdbuf,32);
}


int	CCamOperate::SetJpegEncQuality(HWND hWnd, DWORD value)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = value;
	return SendCMD(hWnd,CMD_JPEG_QUALITY,CMD_METHOD_SET,cmdbuf,4);
}

int	CCamOperate::SetH264Resolution(HWND hWnd, DWORD streamID, const char* resolution)
{
	char cmdbuf[40];
	*(DWORD*)cmdbuf = streamID;
	sprintf_s(cmdbuf+4, 32, "%s",resolution);
	return SendCMD(hWnd,CMD_H264_RESOLUTION,CMD_METHOD_SET,cmdbuf,36);
}

int	CCamOperate::SetH264CodeRate(HWND hWnd, DWORD streamNum, DWORD codeRate, DWORD mode)
{
	char cmdbuf[16];
	*(DWORD*)cmdbuf = streamNum;
	*(DWORD*)(cmdbuf+4) = codeRate;
	*(DWORD*)(cmdbuf+8) = mode;
	return SendCMD(hWnd,CMD_H264_CODE_RATE,CMD_METHOD_SET,cmdbuf,12);
}

int	CCamOperate::SetH264Fps(HWND hWnd, DWORD streamID, const char* fps)
{
	char cmdbuf[40];
	*(DWORD*)cmdbuf = streamID;
	sprintf_s(cmdbuf+4,32,"%s",fps);
	return SendCMD(hWnd,CMD_H264_ENC_FPS,CMD_METHOD_SET,cmdbuf,32);
}

int	CCamOperate::SetH264Fps(HWND hWnd, DWORD streamID,DWORD fps)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = streamID;
	*(DWORD*)(cmdbuf+4) = fps;
	return SendCMD(hWnd,CMD_H264_ENC_FPS,CMD_METHOD_SET,cmdbuf,8);
}

int	CCamOperate::SetH264IFrameInterval(HWND hWnd, int streamID, DWORD interval)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = streamID;
	*(DWORD*)(cmdbuf +4) = interval;
	return SendCMD(hWnd,CMD_H264_IFRAME_INTERVAL,CMD_METHOD_SET,cmdbuf,8);
}

int	CCamOperate::SetH264Profile(HWND hWnd, int streamID, DWORD profile)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = streamID;
	*(DWORD*)(cmdbuf + 4) = profile;
	return SendCMD(hWnd,CMD_H264_ENC_PROFILE,CMD_METHOD_SET,cmdbuf,8);
}

int	CCamOperate::SetH264Denoise(HWND hWnd, char* mode, char* level)
{
	char cmdbuf[80];
	sprintf_s(cmdbuf,"%s",mode);
	sprintf_s(cmdbuf+32, 40, "%s", level);
	return SendCMD(hWnd,CMD_H264_DENOISE,CMD_METHOD_SET,cmdbuf,64);
}

int	CCamOperate::SetCamIPAddr(HWND hWnd,const char* IPAddr)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = inet_addr(IPAddr);
	return SendCMD(hWnd,CMD_NET_IP_ADDR, CMD_METHOD_SET, cmdbuf, 4);
}

int	CCamOperate::SetCamMacAddr(HWND hWnd,BYTE* MacAddr)
{
	char cmdbuf[12];
	memcpy(cmdbuf, MacAddr, 8);
	return SendCMD(hWnd,CMD_NET_MAC_ADDR, CMD_METHOD_SET, cmdbuf, 8);
}

int	CCamOperate::SetTime(HWND hWnd,struct tm *time)
{
	char cmdbuf[128];
	memcpy(cmdbuf,time,sizeof(struct tm));
	return SendCMD(hWnd,CMD_RTC_OPE, CMD_METHOD_SET, cmdbuf, sizeof(struct tm));
}

int	CCamOperate::ReadTime(HWND hWnd)
{
	return SendCMD(hWnd,CMD_RTC_OPE, CMD_METHOD_GET);
}

int	CCamOperate::SwitchFilter(HWND hWnd, DWORD mode)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf	= mode;
	return SendCMD(hWnd,CMD_OPT_SWITCH,CMD_METHOD_SET,cmdbuf,4);
}

int CCamOperate::ResetCamera(HWND hWnd,DWORD mode)
{
	if (0 == mode)
	{
		return SendCMD(hWnd, CMD_RESET_COLD,CMD_METHOD_EXCUTE);
	}
	return SendCMD(hWnd, CMD_RESET_WARM,CMD_METHOD_EXCUTE);
}


int	CCamOperate::EnablePwrSync(HWND hWnd,BOOL flag)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = (DWORD)flag;
	return SendCMD(hWnd,CMD_POWER_SYNC,CMD_METHOD_SET,cmdbuf,4);
}

int	CCamOperate::SetPwrSyncPhase(HWND hWnd,DWORD phase)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = phase;
	return SendCMD(hWnd,CMD_POWER_SYNC_PHASE,CMD_METHOD_SET,cmdbuf,4);
}

int	CCamOperate::SetPwrSyncDelay(HWND hWnd,DWORD delay)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = delay;
	return SendCMD(hWnd,CMD_POWER_SYNC_DELAY,CMD_METHOD_SET,cmdbuf,4);
}

int	CCamOperate::SaveDevParam(HWND hWnd, BYTE *paramList, DWORD cnt)
{
	char *cmdbuf = NULL;
	int nRet = 0;
	int size = cnt*sizeof(DWORD) + 4;
	cmdbuf = new char[size];
	if(!cmdbuf)
	{
		return -1;
	}
	*(DWORD*)cmdbuf = cnt;
	memcpy_s(cmdbuf+4, size, paramList, cnt*sizeof(DWORD));
	nRet = SendCMD(hWnd,CMD_SAVE_CAM_PARAMETERS,CMD_METHOD_EXCUTE,cmdbuf,size);

	delete[] cmdbuf;
	if (nRet < 0)
	{
		return nRet;
	}
	return 0;
}

int	CCamOperate::EnableFlashOutput(HWND hWnd, enum Roseek_SensorRunMode mode, DWORD enable)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = (DWORD)mode;
	*(DWORD*)(cmdbuf+4) = enable;
	return SendCMD(hWnd,CMD_IO_FLASH_OUTPUT,CMD_METHOD_SET,cmdbuf,8);
}

int	CCamOperate::SetFlashPreSync(HWND hWnd,enum Roseek_SensorRunMode mode, DWORD value)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = (DWORD)mode;
	*(DWORD*)(cmdbuf+4) = value;
	return SendCMD(hWnd,CMD_IO_FLASH_PRE_OUTPUT,CMD_METHOD_SET,cmdbuf,8);
}

int	CCamOperate::SetFlashPulseWidth(HWND hWnd, DWORD value)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = (DWORD)value;
	return SendCMD(hWnd,CMD_IO_FLASH_PULSE_WIDTH,CMD_METHOD_SET,cmdbuf,4);
}

int	CCamOperate::SetStrobeFlashFreq(HWND hWnd,const char* freq)
{
	char cmdbuf[40];
	sprintf_s(cmdbuf,freq,32);
	return SendCMD(hWnd,CMD_IO_FLASH_STROBE_FREQ,CMD_METHOD_SET,cmdbuf,32);
}

int	CCamOperate::SetJpegOSD(HWND hWnd, RoseekOsdConfig* pConfig)
{
	char *cmdbuf = NULL;
	cmdbuf = new char[sizeof(RoseekOsdConfig)];
	memcpy_s(cmdbuf,sizeof(RoseekOsdConfig),pConfig,sizeof(RoseekOsdConfig));
	int nRet = SendCMD(hWnd,CMD_JPEG_OSD,CMD_METHOD_SET,cmdbuf,sizeof(RoseekOsdConfig));
	delete[] cmdbuf;
	return nRet;
}

int	CCamOperate::SetH264OSD(HWND hWnd, DWORD index, RoseekOsdConfig* pConfig)
{
	char *cmdbuf = NULL;
	cmdbuf = new char[sizeof(RoseekOsdConfig)+4];
	*(DWORD*)cmdbuf = index;
	memcpy_s(cmdbuf+4,sizeof(RoseekOsdConfig),pConfig,sizeof(RoseekOsdConfig));
	int nRet = SendCMD(hWnd,CMD_H264_OSD,CMD_METHOD_SET,cmdbuf,sizeof(RoseekOsdConfig)+4);
	delete[] cmdbuf;
	return nRet;
}

int	CCamOperate::EnableDHCP(HWND hWnd,DWORD state)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = state;
	return SendCMD(hWnd,CMD_NET_DHCP,CMD_METHOD_SET,cmdbuf,4);
}

int	CCamOperate::SetIPSubnetMask(HWND hWnd, DWORD mask)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = mask;
	return SendCMD(hWnd,CMD_NET_MASK,CMD_METHOD_SET,cmdbuf,4);
}

int	CCamOperate::SetGateway(HWND hWnd, DWORD gateway)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = gateway;
	return SendCMD(hWnd,CMD_NET_GATEWAY,CMD_METHOD_SET,cmdbuf,4);
}

int	CCamOperate::SetDNSServer(HWND hWnd, DWORD server)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = server;
	return SendCMD(hWnd,CMD_NET_DNS_SERVER,CMD_METHOD_SET,cmdbuf,4);
}

int	CCamOperate::SetHostName(HWND hWnd, const char* name)
{
	char *cmdbuf = NULL;
	cmdbuf = new char[256];
	if (!cmdbuf)
	{
		return -1;
	}
	strcpy_s(cmdbuf,256,name);
	int nRet = SendCMD(hWnd,CMD_NET_HOST_NAME,CMD_METHOD_SET,cmdbuf,256);
	delete[] cmdbuf;
	return nRet;
}

int CCamOperate::SetDomainName(HWND hWnd, const char* name)
{
	char *cmdbuf = NULL;
	cmdbuf = new char[64];
	if (!cmdbuf)
	{
		return -1;
	}
	strcpy_s(cmdbuf,64,name);
	int nRet = SendCMD(hWnd,CMD_NET_DOMAIN_NAME,CMD_METHOD_SET,cmdbuf,64);
	delete[] cmdbuf;
	return nRet;
}

int	CCamOperate::SetPortNum(HWND hWnd, const char* name, DWORD port)
{
	char *cmdbuf = NULL;
	cmdbuf = new char[80];
	if (!cmdbuf)
	{
		return -1;
	}
	
	strcpy_s(cmdbuf,64,name);
	*(DWORD*)(cmdbuf+64) = port;
	int nRet = SendCMD(hWnd,CMD_NET_MODULE_PORT_NUM,CMD_METHOD_SET,cmdbuf,68);
	delete[] cmdbuf;
	return nRet;
}

int	CCamOperate::SetH264RTSPLocalAddr(HWND hWnd, DWORD index, const char* addr)
{
	char cmdbuf[64];
	*(DWORD*)cmdbuf = index;
	strcpy_s(cmdbuf+4,60,addr);
	return SendCMD(hWnd,CMD_NET_RTSP_LOCAL,CMD_METHOD_SET,cmdbuf,64);
}

int	CCamOperate::EnableSaveTrgJpegToSD(HWND hWnd, DWORD state)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = state;
	return SendCMD(hWnd,CMD_SD_SAVE_JPEG,CMD_METHOD_SET,cmdbuf,4);
}

int	CCamOperate::SetCurPIrisByStep(HWND hWnd, DWORD step)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = step;
	return SendCMD(hWnd,CMD_PIRIS_STEP_CTRL,CMD_METHOD_SET,cmdbuf,4);
}

int	CCamOperate::SetCurPIrisByFValue(HWND hWnd, float fValue)
{
	char cmdbuf[8];
	*(float*)cmdbuf = fValue;
	return SendCMD(hWnd,CMD_PIRIS_FVALUE_CTRL,CMD_METHOD_SET,cmdbuf,4);
}

int	CCamOperate::SetPIrisLenType(HWND hWnd, const char* type)
{
	char *cmdbuf = NULL;
	cmdbuf = new char[32];
	if (!cmdbuf)
	{
		return -1;
	}
	strcpy_s(cmdbuf,32,type);
	int nRet = SendCMD(hWnd, CMD_PIRIS_TYPE, CMD_METHOD_SET, cmdbuf, 32);
	delete[] cmdbuf;
	return nRet;
}

int CCamOperate::SetDCIrisMode(HWND hWnd, DWORD mode)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = mode;
	return SendCMD(hWnd,CMD_DCIRIS_CTRL,CMD_METHOD_SET,cmdbuf,4);
}

int CCamOperate::GetTemperature(HWND hWnd)
{
	return SendCMD(hWnd, CMD_TEMP, CMD_METHOD_GET);
}

int CCamOperate::SaveEncryptionInfo(HWND hWnd, DWORD flagAddr, DWORD flag, DWORD licAddr, char lic[256])
{
	char *cmdbuf = NULL;
	cmdbuf = new char[256+16];
	if (cmdbuf == NULL)
	{
		return FALSE;
	}
	*(DWORD*) cmdbuf = flagAddr;
	*(DWORD*) (cmdbuf+4) = flag;
	*(DWORD*) (cmdbuf+8) = licAddr;
	memcpy_s(cmdbuf+12,256,lic,256);
	int nRet = SendCMD(hWnd,CMD_AUTHOR_OPE,CMD_METHOD_SET,cmdbuf,256+12);
	if (cmdbuf != NULL)
	{
		delete[] cmdbuf;
	}
	return nRet;
}

int CCamOperate::ReadEncryptionInfo(HWND hWnd, DWORD flagAddr, DWORD licAddr)
{
	char cmdbuf[16];
	*(DWORD*) cmdbuf = flagAddr;
	*(DWORD*) (cmdbuf+4) = licAddr;
	return SendCMD(hWnd,CMD_AUTHOR_OPE,CMD_METHOD_GET,cmdbuf,8);
}


int CCamOperate::ResumeAllParams(HWND hWnd)
{
	return SendCMD(hWnd, CMD_RESUME_CAM_PARAMETERS, CMD_METHOD_EXCUTE);
}

int CCamOperate::SaveLoginInfo(HWND hWnd, RoseekUserInfo *pInfo)
{
	char *cmdbuf = NULL;
	int nRet = 0;
	cmdbuf = new char[sizeof(RoseekUserInfo)];
	memcpy_s(cmdbuf,sizeof(RoseekUserInfo),pInfo,sizeof(RoseekUserInfo));
	nRet =  SendCMD(hWnd,CMD_GEN_LOGIN_INFO,CMD_METHOD_SET,cmdbuf,sizeof(RoseekUserInfo));
	delete[] cmdbuf;
	return nRet;
}

int	CCamOperate::EnableJpegOutput(HWND hWnd, DWORD flag)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = flag;
	return SendCMD(hWnd, CMD_ACQ_JPEG_OUTPUT,CMD_METHOD_SET, cmdbuf , 4);
}

int	CCamOperate::ConfigIO(HWND hWnd, DWORD index, DWORD config)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = index;
	*(DWORD*)(cmdbuf + 4) = config;
	return SendCMD(hWnd, CMD_IO_GPIO_CONFIG,CMD_METHOD_SET, cmdbuf , 8);
}

int	CCamOperate::ConfigISO(HWND hWnd, DWORD dir, DWORD index, DWORD config)
{
	char cmdbuf[16];
	*(DWORD*)cmdbuf = dir;
	*(DWORD*)(cmdbuf + 4) = index;
	*(DWORD*)(cmdbuf + 8) = config;
	return SendCMD(hWnd, CMD_IO_ISO_CONFIG,CMD_METHOD_SET, cmdbuf , 12);
}


int	CCamOperate::EnableHDMI(HWND hWnd, DWORD state)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = state;
	return SendCMD(hWnd, CMD_H264_HDMI,CMD_METHOD_SET, cmdbuf , 4);
}

int	CCamOperate::EnableCVBS(HWND hWnd, DWORD state)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = state;
	return SendCMD(hWnd, CMD_H264_CVBS,CMD_METHOD_SET, cmdbuf , 4);
}

int	CCamOperate::AppSetCaptureMode(HWND hWnd, enum RoseekFconRunMode mode)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = (DWORD)mode;
	return SendCMD(hWnd, CMD_APP_CAPTURE_MODE,CMD_METHOD_SET, cmdbuf , 4);
}

int	CCamOperate::AppCapturePics(HWND hWnd, DWORD id, DWORD detail)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = id;
	*(DWORD*)(cmdbuf+4) = detail;
	return SendCMD(hWnd, CMD_APP_CAPTURE_CMD,CMD_METHOD_EXCUTE, cmdbuf , 8);
}

int	CCamOperate::AppSaveCapturePicToSD(HWND hWnd,BOOL flag)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = (DWORD)flag;
	return SendCMD(hWnd, CMD_APP_CAPTURE_SAVE_SD,CMD_METHOD_SET, cmdbuf , 4);	
}

int	CCamOperate::SetTrgFrameAdjMode(HWND hWnd, DWORD mode)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = mode;
	return SendCMD(hWnd, CMD_ACQ_TRGFRAME_ADJMODE,CMD_METHOD_SET, cmdbuf , 4);
}

int	CCamOperate::SetTrgFrameShuttime(HWND hWnd, DWORD shuttime)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = shuttime;
	return SendCMD(hWnd, CMD_ACQ_TRGFRAME_SHUTTIME,CMD_METHOD_SET, cmdbuf , 4);
}

int	CCamOperate::SetTrgFrameGain(HWND hWnd, float gain)
{
	char cmdbuf[12];
	*(float*)cmdbuf = gain;
	return SendCMD(hWnd, CMD_ACQ_TRGFRAME_GAIN,CMD_METHOD_SET, cmdbuf , 4);
}

int	CCamOperate::SetTimeZone(HWND hWnd, int timeZone)
{
	char cmdbuf[8];
	*(int*)cmdbuf = timeZone;
	return SendCMD(hWnd, CMD_TIME_ZONE,CMD_METHOD_SET, cmdbuf , 4);
}

int	CCamOperate::SetNTPServer(HWND hWnd, DWORD server, DWORD syncTime)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = server;
	*(DWORD*)(cmdbuf+4) = syncTime;
	return SendCMD(hWnd, CMD_NTP_SERVER,CMD_METHOD_SET, cmdbuf , 8);
}

int	CCamOperate::SetFTPServe(HWND hWnd, DWORD state)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = state;
	return SendCMD(hWnd, CMD_NET_FTP_SERVE,CMD_METHOD_SET, cmdbuf , 4);
}

int	CCamOperate::SetFTPServerInfo(HWND hWnd, DWORD ip, DWORD port)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = ip;
	*(DWORD*)(cmdbuf+4) = port;
	return SendCMD(hWnd, CMD_NET_FTP_SERVER_INFO,CMD_METHOD_SET, cmdbuf , 8);
}

int	CCamOperate::SetFTPLoginInfo(HWND hWnd, const char* username, const char* password)
{
	char cmdbuf[256];
	strcpy_s(cmdbuf,128,username);
	strcpy_s(cmdbuf+128,64,password);
	return SendCMD(hWnd, CMD_NET_FTP_LOGIN_INFO,CMD_METHOD_SET, cmdbuf , 128+64);
}

int	CCamOperate::SetUartState(HWND hWnd, DWORD index, DWORD state)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = index;
	*(DWORD*)(cmdbuf+4) = state;
	return SendCMD(hWnd, CMD_UART_ENABLE,CMD_METHOD_SET, cmdbuf , 8);
}

int	CCamOperate::SetUartBaudRate(HWND hWnd, DWORD index, DWORD rate)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = index;
	*(DWORD*)(cmdbuf+4) = rate;
	return SendCMD(hWnd, CMD_UART_BUADRATE,CMD_METHOD_SET, cmdbuf , 8);
}

int	CCamOperate::SetUartWorkMode(HWND hWnd, DWORD index, DWORD mode)
{
	char cmdbuf[12];
	*(DWORD*)cmdbuf = index;
	*(DWORD*)(cmdbuf+4) = mode;
	return SendCMD(hWnd, CMD_UART_WORKMODE,CMD_METHOD_SET, cmdbuf , 8);
}

int	CCamOperate::SetAfeLevel(HWND hWnd,DWORD level)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = level;
	return SendCMD(hWnd, CMD_ACQ_AFE_LEVEL,CMD_METHOD_SET, cmdbuf , 4);
}

int	CCamOperate::SetImgContrast(HWND hWnd, DWORD value)
{
	char cmdbuf[8];
	float fValue = (float)(value/100.0);
	SetLutGamma(hWnd, 0, fValue);
	CMDItem_t cmdInfo;
	memset(&cmdInfo, 0, sizeof(CMDItem_t));
	cmdInfo.attribute = CMD_PROC_CONTRAST;
	cmdInfo.dataBackLen = 0;
	cmdInfo.dataSendLen = 4;
	cmdInfo.hWndNotify = hWnd;
	cmdInfo.result = CMD_PROCESS_SUCCESS;
	cmdInfo.method  = CMD_METHOD_SET;
	cmdInfo.pDataSend = cmdbuf;
	::SendMessage(hWnd, MSG_NOTIFY_CMD_FINISH, (WPARAM)&cmdInfo, 0);
	return 0;
}


int	CCamOperate::SetLedDriverMode(HWND hWnd, DWORD mode)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = mode;
	return SendCMD(hWnd, CMD_IO_LEDDRIVER_MODE,CMD_METHOD_SET, cmdbuf , 4);
}

int	CCamOperate::SetLedDriverStrength(HWND hWnd, DWORD strength)
{
	char cmdbuf[8];
	*(DWORD*)cmdbuf = strength;
	return SendCMD(hWnd, CMD_IO_LEDDRIVER_STRENGTH,CMD_METHOD_SET, cmdbuf , 4);
}






